/**  
 * @Title:  DataSouceConfiguration.java   
 * @Package com.platform.config   
 * @Description:    TODO(用一句话描述该文件做什么)   
 * @author: 吴元森 
 * @date:   2019年12月30日 下午4:40:09   
 * @version V1.0 
 * @Copyright: 2019 吴元森.
 */
package com.platform.config;

import java.util.Map;
import java.util.Properties;

import javax.sql.DataSource;

import org.mybatis.spring.SqlSessionFactoryBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.interceptor.TransactionInterceptor;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.google.common.collect.Maps;
import com.platform.ext.mybatis.dynamic.ds.DynamicDataSource;

/**   
 * @ClassName:  DataSouceConfiguration   
 * @Description:装配数据源，除了主数据源以为其余数据源均来自系统数据库数据源信息配置表。   
 * @author: 吴元森 
 * @date:   2019年12月30日 下午4:40:09   
 *     
 * @Copyright: 2019 吴元森.  
 */
@Configuration
public class DataSouceConfiguration extends BaseConfig{
	
	private Logger log = LoggerFactory.getLogger(DataSouceConfiguration.class);
	
	@Autowired
	private PlatformTransactionManager transactionManager;
	
	@Bean(name="master",initMethod = "init",destroyMethod = "close")
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource master() {
		log.info("\n----------------------------------------------------------\n\t" +
                "系统配置初始化: \t\t装配系统核心数据源\n" +
                "----------------------------------------------------------");
		DruidDataSource druidDataSource = DruidDataSourceBuilder.create().build();
        return druidDataSource;
    }
	
	@Bean(name="dynamicDataSource")
    public DataSource dynamicDataSource() {
		DynamicDataSource dynamicDataSource = DynamicDataSource.getInstance();
		Map<Object,Object> targetDataSources = Maps.newConcurrentMap();
		targetDataSources.put("master",master());
		// 将 master 数据源作为默认指定的数据源
        dynamicDataSource.setDefaultDataSource(master());
        // 将 master 和 slave 数据源作为指定的数据源
        dynamicDataSource.setTargetDataSources(targetDataSources);
        dynamicDataSource.afterPropertiesSet();
        return dynamicDataSource;
    }
	 
	@Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean() throws Exception {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        // 配置数据源，此处配置为关键配置，如果没有将 dynamicDataSource作为数据源则不能实现切换
        sessionFactory.setDataSource(dynamicDataSource());
        sessionFactory.setTypeAliasesPackage("com.platform.dto");    // 扫描Model
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sessionFactory.setMapperLocations(resolver.getResources("classpath*:mapper/*.xml"));    // 扫描映射文件
        sessionFactory.setConfigLocation(resolver.getResource("classpath:mybatis.cfg.xml"));	//mybatis配置文件
        return sessionFactory;
    }
	
	/**
	 * @Title: transactionAttributeSource   
	 * @Description: 注解声明式事务配置
	 * @return      
	 * TransactionAttributeSource
	 */
	@Bean("txInterceptor")
	public TransactionInterceptor txAdvice() {
		Properties properties = new Properties();
//		properties.setProperty("get*", "PROPAGATION_REQUIRED,readOnly");
//		properties.setProperty("query*", "PROPAGATION_REQUIRED,readOnly");
//		properties.setProperty("load*", "PROPAGATION_REQUIRED,readOnly");
//		properties.setProperty("list*", "PROPAGATION_REQUIRED,readOnly");
//		properties.setProperty("select*", "PROPAGATION_REQUIRED,readOnly");

		properties.setProperty("add*", "PROPAGATION_REQUIRED,-Exception");
		properties.setProperty("insert*", "PROPAGATION_REQUIRED,-Exception");
		properties.setProperty("save*", "PROPAGATION_REQUIRED,-Exception");
		properties.setProperty("update*", "PROPAGATION_REQUIRED,-Exception");
		properties.setProperty("delete*", "PROPAGATION_REQUIRED,-Exception");
		properties.setProperty("remove*", "PROPAGATION_REQUIRED,-Exception");
//		properties.setProperty("*", "PROPAGATION_REQUIRED,-Exception");
		TransactionInterceptor tsi = new TransactionInterceptor(transactionManager, properties);
		return tsi;
	}

	@Bean
	public BeanNameAutoProxyCreator txProxy() {
		BeanNameAutoProxyCreator creator = new BeanNameAutoProxyCreator();
		creator.setInterceptorNames("txInterceptor");
		creator.setBeanNames("*Impl");
		creator.setProxyTargetClass(true);
		return creator;
	}

}
